import { Destroyable, react, reactJson, Event, track, HasOwner, createNextAnimateFrameEvent } from "xbsj-xe2/dist-node/xe2-base-utils";
import { MyProjectManager } from "../MyProjectManager";
import { getFeatureDataset, getFeatureClassTree } from '@/api';
import { FeatureChild, FeatureTransformedChild } from '@/scripts/dataTypes/interface'
import { ESGeoLineString, ESGltfModel, ESGeoPolygon } from "esobjs-xe2-plugin/dist-node/esobjs-xe2-plugin-main";
import { ObjResettingWithEvent, SceneObject } from 'xbsj-xe2/dist-node/xe2-base-objects';
import { ElMessage } from "element-plus";
import { findMaxNum, calculateDistanceInMeters, getPints, computeRot, computeInterpolationPoints, getsceneObjNumfromSceneTree } from '@/scripts/utils';
import { reqGetTextureList, reqWaterRepair } from "@/api";
import { getMinMaxCorner } from "xbsj-xe2/dist-node/xe2-base-objects";

import * as Cesium from "cesium";
// import { ESGeoExtrudedPolygonUFMS } from "../ESGeoExtrudedPolygonUFMS";
import { ESRtsPolygon } from "../esobjs/ESRtsPolygon";
import { ESRtsEexturedPolygon } from "../esobjs/ESRtsEexturedPolygon";

class PolygonChoose extends Destroyable {
    constructor(waterMend: WaterMend, owner: MyProjectManager) {
        super();
        const viewer = owner.activeViewer
        if (!viewer) return;
        if (!waterMend.currentDataSet) {
            ElMessage.error('请先选择数据集')
            waterMend.isHighlight = ""
            return;
        } else if (!waterMend.currentFeatureClass) {
            ElMessage.error('请先选择要素类')
            waterMend.isHighlight = ""
            return;
        }

        const sceneObject = owner.createSceneObject(ESRtsPolygon) as ESRtsPolygon
        sceneObject.filled = true
        sceneObject.fillColor = [0.0392156862745098, 0.9137254901960784, 0.9607843137254902, 0.4];
        sceneObject.name = "创建多边形"
        sceneObject.strokeWidth = 2
        sceneObject.create = true

        owner.propSceneTree = {
            createOrEdit: 'create',
            propType:"waterMend",
            sceneObject: sceneObject,
        }

        this.dispose(()=>{
            if (!owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(sceneObject.id)) {
                sceneObject.editing = false
                sceneObject && owner.destroySceneObject(sceneObject);
                owner.propSceneTree = undefined
            }
        })
    }
}
class ExtrudedPolygonChoose extends Destroyable {
    constructor(waterMend: WaterMend, owner: MyProjectManager) {
        super();
        const viewer = owner.activeViewer
        if (!viewer) return;
        if (!waterMend.currentDataSet) {
            ElMessage.error('请先选择数据集')
            waterMend.isHighlight = ""
            return;
        } else if (!waterMend.currentFeatureClass) {
            ElMessage.error('请先选择要素类')
            waterMend.isHighlight = ""
            return;
        }
        const sceneObject = owner.createSceneObject(ESRtsEexturedPolygon) as ESRtsEexturedPolygon
        sceneObject.filled = true
        sceneObject.fillColor = [0.0392156862745098, 0.9137254901960784, 0.9607843137254902, 0.4];
        sceneObject.strokeWidth = 2
        sceneObject.name = "创建多边形体"
        sceneObject.create = true

        owner.propSceneTree = {
            createOrEdit: 'create',
            propType:"waterMend",
            sceneObject: sceneObject,
        }

        this.dispose(()=>{
            if (!owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(sceneObject.id)) {
                sceneObject.editing = false
                sceneObject && owner.destroySceneObject(sceneObject);
                owner.propSceneTree = undefined
            }
        })

    }
}

export class WaterMend extends HasOwner<MyProjectManager> {

    // 数据集列表
    private _dataSet = this.dv(reactJson<any>([]));
    get dataSet() { return this._dataSet.value }
    set dataSet(value) { this._dataSet.value = value }
    get dataSetChanged() { return this._dataSet.changed }

    // 被选中的数据集
    private _currentDataSet = this.dv(react<string>(""));
    get currentDataSet() { return this._currentDataSet.value; }
    set currentDataSet(value) { this._currentDataSet.value = value }
    get currentDataSetChanged() { return this._currentDataSet.changed; }

    // 要素类树
    private _featureClassTree = this.dv(reactJson<any>([]));
    get featureClassTree() { return this._featureClassTree.value }
    set featureClassTree(value) { this._featureClassTree.value = value }
    get featureClassTreeChanged() { return this._featureClassTree.changed }

    // 被选中的要素类id
    private _currentFeatureClass = this.dv(react<string>(""));
    get currentFeatureClass() { return this._currentFeatureClass.value; }
    set currentFeatureClass(value) { this._currentFeatureClass.value = value }
    get currentFeatureClassChanged() { return this._currentFeatureClass.changed; }

     // 被选中的要素类名称
     private _currentFeatureClassName = this.dv(react<string>(""));
     get currentFeatureClassName() { return this._currentFeatureClassName.value; }
     set currentFeatureClassName(value) { this._currentFeatureClassName.value = value }
     get currentFeatureClassNameChanged() { return this._currentFeatureClassName.changed; }

    // 标记点击
    private _isHighlight = this.dv(react<string>(""));
    get isHighlight() { return this._isHighlight.value; }
    set isHighlight(value) { this._isHighlight.value = value }
    get isHighlightChanged() { return this._isHighlight.changed; }

    private _event = this.dv(createNextAnimateFrameEvent(this.isHighlightChanged));
    private _pickSetting = this.dv(new ObjResettingWithEvent(this._event, () => {

        if (!this.isHighlight) {
            return undefined
        }

        switch (this.isHighlight) {
            case 'polygon':
                return new PolygonChoose(this, this.owner);
            case 'extrudedPolygon':
                return new ExtrudedPolygonChoose(this, this.owner);
            default: return undefined
        }

    }))
    get pickSetting() { return this._pickSetting; }

    /**递归children，过滤字段*/
    transformChildren(children: FeatureChild[]): FeatureTransformedChild[] {
        if (Array.isArray(children)) {
            return children.map(child => ({
                label: child.className,
                value: child.id,
                children: child.children ? this.transformChildren(child.children) : []
            }));
        }
        return [];
    }

    // 获取数据集列表
    async getDatasetList() {
        const res = await getFeatureDataset(this._tileServiceName)
        // @ts-ignore
        if (res.status !== 'ok') return
        this._dataSet.value = res.data
    }

    // 获取要素类树
    async getTreeList() {
        const res = await getFeatureClassTree(this.currentDataSet)
        // @ts-ignore
        if (res.status !== 'ok') return
        this.featureClassTree = this.transformChildren(res.data)
    }

    // 水面修补
    async waterRepair(sceneTree: any) {
        const params = {
            "tileServiceName": this._tileServiceName,
            "datasetName": this.currentDataSet,
            "featureClassId": this.currentFeatureClass,
            "sceneTree": sceneTree,
        }
        try {
            const res = await reqWaterRepair(params)
            // @ts-ignore
            if (res.status !== 'ok') {
                return "errer"
            } else {
                ElMessage.success('创建成功')
                return "ok"
            }
        } catch (error) {
            console.error(error)
            return "errer"
        }

    }

    // 获取纹理列表
    async getTextureList(param:any) {
        try {
            const res = await reqGetTextureList(param)
            // @ts-ignore
            if (res.status !== 'ok') return [];
            return {
                tableData: res.data.data,
                total: res.data.total
            }

        } catch (error) {
            console.error(error)
        }
    }

    // 初始化
    async init() {
        // 获取数据集列表
        await this.getDatasetList()
    }

    clear() {
        this.isHighlight = ""
    }

    constructor(public _tileServiceName: string, owner: MyProjectManager) {
        super(owner);
        {
            // 监听数据集变化 根据数据集获取要素类树 
            const updata = (val: string) => {
                this.getTreeList()
            }
            this.dispose(this.currentDataSetChanged.don(updata))
        }
    }
}















